/*
 *Named Entity Annotation Version 1.0.0 Copyright (C) 2007 Tran Quoc Tri
 *
 *Named Entity Annotation is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation.
 *
 *This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY. See the GNU General Public License for more details.
 *
 *Incase you have a bug to report or a feature to request, please email to quoctrict@gmail.com. All feedbacks are wellcome
 *
 *---
 *Tran Quoc Tri
 *Faculty of Computer Science
 *University of Information Technology, VNU-HCMC
 *34 Truong Dinh, District 3rd , Ho Chi Minh City, VietNam
 *Email:tritq@uit.edu.vn, quoctrict@gmail.com 
  
 */
using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;
using System.Xml;
using System.Threading;
using System.IO;
using System.Text.RegularExpressions;
using Flobbster.Windows.Forms;
using AMS.Profile;

namespace NEAnnotation
{
	/// <summary>
	/// Summary description for Form1.
	/// </summary>
	public class FormMain : System.Windows.Forms.Form
	{
		private System.ComponentModel.IContainer components;
		#region /* Global variables */

		private string stFileTag = Application.StartupPath + "\\" + "ner.tagset";
		private string stFileHelp = Application.StartupPath + "\\neannotation.mht";
		private string stFileConfig = Application.StartupPath + "\\" + "BioCaster.ini";
		private Hashtable htbClasses = new Hashtable();
		private Hashtable htbColors = new Hashtable();
		private ArrayList arrActiveTags = new ArrayList();
		private ArrayList arrEntities = new ArrayList();
		private ArrayList arrIDs = new ArrayList();
		
		private ArrayList arrUndo = new ArrayList();
		private ArrayList arrRedo = new ArrayList();
		private string stLanguage = "";
		private string stEncoding = "ASCII";
		private string stCurClass = "";
		private string stFileName = "";
		private bool isUpdating = false;
		private bool hasChange = false;
		private int nCurPos = 0;
		private System.Text.Encoding curEncoding ;
		private XmlDocument xDoc = new XmlDocument();

		private System.Windows.Forms.StatusBar statusBar1;
		private System.Windows.Forms.ImageList imageList1;
		private System.Windows.Forms.OpenFileDialog openFileDialog1;
		private System.Windows.Forms.SaveFileDialog saveFileDialog1;
		private System.Windows.Forms.StatusBarPanel statusBarPanel1;
		private System.Windows.Forms.HelpProvider helpProvider1;
		private System.Windows.Forms.StatusBarPanel statusBarPanel2;
		private System.Windows.Forms.MainMenu mainMenu1;
		private System.Windows.Forms.MenuItem menuItemFile;
		private System.Windows.Forms.MenuItem menuItemOpen;
		private System.Windows.Forms.MenuItem menuItemSave;
		private System.Windows.Forms.MenuItem menuItemSaveAs;
		private System.Windows.Forms.MenuItem menuItemExit;
		private System.Windows.Forms.MenuItem menuItemEdit;
		private System.Windows.Forms.MenuItem menuItemUndo;
		private System.Windows.Forms.MenuItem menuItemRedo;
		private System.Windows.Forms.MenuItem menuItemEncoding;
		private System.Windows.Forms.MenuItem menuItemASCII;
		private System.Windows.Forms.MenuItem menuItemUnicode;
		private System.Windows.Forms.MenuItem menuItemUTF8;
		private System.Windows.Forms.Panel panelMain;
		private System.Windows.Forms.Panel panelRight;
		private System.Windows.Forms.TabControl tabControl1;
		private System.Windows.Forms.TabPage tabPageProperties;
		private System.Windows.Forms.PropertyGrid propertyGrid1;
		private System.Windows.Forms.MenuItem menuItemNextEntity;
		private System.Windows.Forms.MenuItem menuItemPrevEntity;
		private System.Windows.Forms.MenuItem Find;
		private System.Windows.Forms.ToolBar toolBar1;
		private System.Windows.Forms.ToolBarButton toolBarButtonOpen;
		private System.Windows.Forms.ToolBarButton toolBarButtonSave;
		private System.Windows.Forms.ToolBarButton toolBarButtonUndo;
		private System.Windows.Forms.ToolBarButton toolBarButtonRedo;
		private System.Windows.Forms.FolderBrowserDialog folderBrowserDialog1;
		private System.Windows.Forms.Splitter splitter1;
		private System.Windows.Forms.Panel panelLeft;
		private System.Windows.Forms.RichTextBox rtbText;
		private System.Windows.Forms.ToolBarButton toolBarButtonSep1;
		private System.Windows.Forms.MenuItem menuItem2;
		private System.Windows.Forms.MenuItem menuItem3;
		private System.Windows.Forms.MenuItem menuItemHelp;
		private System.Windows.Forms.MenuItem menuItemHelpTopic;
		private System.Windows.Forms.MenuItem menuItemAbout;
		private System.Windows.Forms.TabPage tabPageAttributes;
		private System.Windows.Forms.GroupBox groupBox1;
		private System.Windows.Forms.ListBox lbxTerms;
		private System.Windows.Forms.MenuItem menuItemTagset;
		private System.Windows.Forms.GroupBox groupBox2;
		private Flobbster.Windows.Forms.PropertyBag bag1;
		#endregion

		#region /* Define structs */

		struct Term
		{
			public string stID, stLabel, stLanguage;
			public Term(string sID, string sLabel, string sLanguage)
			{
				stID = sID;
				stLabel = sLabel;
				stLanguage = sLanguage;
			}
		};
		struct RootTerm
		{
			public string stID, stLabel;
			public ArrayList arrSynonymTerms;
			public RootTerm(string sID, string sLabel)
			{
				stID = sID;
				stLabel = sLabel;
				arrSynonymTerms = new ArrayList();
				
			}
			
		};
		struct Entity
		{
			public string stClass, stTag;
			public int nStart, nLength;
			public Entity(string  sClass, string sTag, int Start, int Len)
			{
				stClass = sClass;
				stTag = sTag;
				nStart = Start;
				nLength = Len;
			}
			public Entity(string  sClass, string sTag, int Start)
			{
				stClass = sClass;
				stTag = sTag;
				nStart = Start;
				nLength = 0;
			}
		};
		struct TagLabel
		{
			public string ClassName, Color;
			public ArrayList Atributes;
			public Char Shortcut;
			public string Description;
			public bool	BeginGroup;
			public TagLabel(string s)
			{
				ClassName = s;
				Color = "";
				Shortcut = '0';
				Description = "";
				BeginGroup = false;
				Atributes = new ArrayList();
			}
		}
		struct TagAttribute
		{
			public string Name, Values;
			public TagAttribute(string s)
			{
				Name = s;
				Values = "";
			}
		}

		public int FindTag(ref ArrayList arrTags, string tagName)
		{
			for (int i = 0 ; i < arrTags.Count; i++)
			{
				TagLabel tag = (TagLabel)arrTags[i];
				if(tag.ClassName == tagName)
					return i;
			}
			return -1;
		}
		
		#endregion

		#region /* Define shortcut and the search function */
		Shortcut[] shortcut = new Shortcut[]{
												Shortcut.Ctrl0,
												Shortcut.Ctrl1,
												Shortcut.Ctrl2,
												Shortcut.Ctrl3,
												Shortcut.Ctrl4,
												Shortcut.Ctrl5,
												Shortcut.Ctrl6,
												Shortcut.Ctrl7,
												Shortcut.Ctrl8,
												Shortcut.Ctrl9,
												Shortcut.CtrlA,
												Shortcut.CtrlB,
												Shortcut.CtrlC,
												Shortcut.CtrlD,
												Shortcut.CtrlE,
												Shortcut.CtrlF,
												Shortcut.CtrlG,
												Shortcut.CtrlH,
												Shortcut.CtrlI,
												Shortcut.CtrlJ,
												Shortcut.CtrlK,
												Shortcut.CtrlL,
												Shortcut.CtrlM,
												Shortcut.CtrlN,
												Shortcut.CtrlO,
												Shortcut.CtrlP,
												Shortcut.CtrlQ,
												Shortcut.CtrlR,
												Shortcut.CtrlS,
												Shortcut.CtrlT,
												Shortcut.CtrlU,
												Shortcut.CtrlV,
												Shortcut.CtrlW,
												Shortcut.CtrlX,
												Shortcut.CtrlY,
												Shortcut.CtrlZ
											};
		private Shortcut GetShortCut(string s)
		{
			for (int i=0;i<shortcut.Length;i++)
			{
				if(shortcut[i].ToString() == s)
					return shortcut[i];
			}
			return shortcut[0];
		}
		#endregion
		public FormMain()
		{
			//
			// Required for Windows Form Designer support
			//
			InitializeComponent();
					
			//
			// TODO: Add any constructor code after InitializeComponent call
			//
		}

		/// <summary>
		/// Clean up any resources being used.
		/// </summary>
		protected override void Dispose( bool disposing )
		{
			if( disposing )
			{
				if (components != null) 
				{
					components.Dispose();
				}
			}
			base.Dispose( disposing );
		}

		#region Windows Form Designer generated code
		/// <summary>
		/// Required method for Designer support - do not modify
		/// the contents of this method with the code editor.
		/// </summary>
		private void InitializeComponent()
		{
			this.components = new System.ComponentModel.Container();
			System.Resources.ResourceManager resources = new System.Resources.ResourceManager(typeof(FormMain));
			this.statusBar1 = new System.Windows.Forms.StatusBar();
			this.statusBarPanel1 = new System.Windows.Forms.StatusBarPanel();
			this.statusBarPanel2 = new System.Windows.Forms.StatusBarPanel();
			this.imageList1 = new System.Windows.Forms.ImageList(this.components);
			this.openFileDialog1 = new System.Windows.Forms.OpenFileDialog();
			this.saveFileDialog1 = new System.Windows.Forms.SaveFileDialog();
			this.helpProvider1 = new System.Windows.Forms.HelpProvider();
			this.mainMenu1 = new System.Windows.Forms.MainMenu();
			this.menuItemFile = new System.Windows.Forms.MenuItem();
			this.menuItemOpen = new System.Windows.Forms.MenuItem();
			this.menuItemSave = new System.Windows.Forms.MenuItem();
			this.menuItemSaveAs = new System.Windows.Forms.MenuItem();
			this.menuItem3 = new System.Windows.Forms.MenuItem();
			this.menuItemExit = new System.Windows.Forms.MenuItem();
			this.menuItemEdit = new System.Windows.Forms.MenuItem();
			this.menuItemUndo = new System.Windows.Forms.MenuItem();
			this.menuItemRedo = new System.Windows.Forms.MenuItem();
			this.menuItem2 = new System.Windows.Forms.MenuItem();
			this.menuItemEncoding = new System.Windows.Forms.MenuItem();
			this.menuItemASCII = new System.Windows.Forms.MenuItem();
			this.menuItemUnicode = new System.Windows.Forms.MenuItem();
			this.menuItemUTF8 = new System.Windows.Forms.MenuItem();
			this.Find = new System.Windows.Forms.MenuItem();
			this.menuItemNextEntity = new System.Windows.Forms.MenuItem();
			this.menuItemPrevEntity = new System.Windows.Forms.MenuItem();
			this.menuItemTagset = new System.Windows.Forms.MenuItem();
			this.menuItemHelp = new System.Windows.Forms.MenuItem();
			this.menuItemHelpTopic = new System.Windows.Forms.MenuItem();
			this.menuItemAbout = new System.Windows.Forms.MenuItem();
			this.panelMain = new System.Windows.Forms.Panel();
			this.panelLeft = new System.Windows.Forms.Panel();
			this.groupBox2 = new System.Windows.Forms.GroupBox();
			this.rtbText = new System.Windows.Forms.RichTextBox();
			this.splitter1 = new System.Windows.Forms.Splitter();
			this.panelRight = new System.Windows.Forms.Panel();
			this.groupBox1 = new System.Windows.Forms.GroupBox();
			this.tabControl1 = new System.Windows.Forms.TabControl();
			this.tabPageAttributes = new System.Windows.Forms.TabPage();
			this.lbxTerms = new System.Windows.Forms.ListBox();
			this.tabPageProperties = new System.Windows.Forms.TabPage();
			this.propertyGrid1 = new System.Windows.Forms.PropertyGrid();
			this.toolBar1 = new System.Windows.Forms.ToolBar();
			this.toolBarButtonOpen = new System.Windows.Forms.ToolBarButton();
			this.toolBarButtonSave = new System.Windows.Forms.ToolBarButton();
			this.toolBarButtonSep1 = new System.Windows.Forms.ToolBarButton();
			this.toolBarButtonUndo = new System.Windows.Forms.ToolBarButton();
			this.toolBarButtonRedo = new System.Windows.Forms.ToolBarButton();
			this.folderBrowserDialog1 = new System.Windows.Forms.FolderBrowserDialog();
			((System.ComponentModel.ISupportInitialize)(this.statusBarPanel1)).BeginInit();
			((System.ComponentModel.ISupportInitialize)(this.statusBarPanel2)).BeginInit();
			this.panelMain.SuspendLayout();
			this.panelLeft.SuspendLayout();
			this.groupBox2.SuspendLayout();
			this.panelRight.SuspendLayout();
			this.tabControl1.SuspendLayout();
			this.tabPageAttributes.SuspendLayout();
			this.tabPageProperties.SuspendLayout();
			this.SuspendLayout();
			// 
			// statusBar1
			// 
			this.statusBar1.Location = new System.Drawing.Point(0, 731);
			this.statusBar1.Name = "statusBar1";
			this.statusBar1.Panels.AddRange(new System.Windows.Forms.StatusBarPanel[] {
																						  this.statusBarPanel1,
																						  this.statusBarPanel2});
			this.statusBar1.ShowPanels = true;
			this.statusBar1.Size = new System.Drawing.Size(1272, 22);
			this.statusBar1.TabIndex = 0;
			this.statusBar1.Text = "statusBar1";
			// 
			// statusBarPanel1
			// 
			this.statusBarPanel1.Text = "File Name";
			this.statusBarPanel1.Width = 600;
			// 
			// statusBarPanel2
			// 
			this.statusBarPanel2.Text = "Press F1 for help";
			this.statusBarPanel2.Width = 200;
			// 
			// imageList1
			// 
			this.imageList1.ImageSize = new System.Drawing.Size(16, 16);
			this.imageList1.ImageStream = ((System.Windows.Forms.ImageListStreamer)(resources.GetObject("imageList1.ImageStream")));
			this.imageList1.TransparentColor = System.Drawing.Color.Transparent;
			// 
			// openFileDialog1
			// 
			this.openFileDialog1.Multiselect = true;
			this.openFileDialog1.RestoreDirectory = true;
			// 
			// saveFileDialog1
			// 
			this.saveFileDialog1.RestoreDirectory = true;
			// 
			// mainMenu1
			// 
			this.mainMenu1.MenuItems.AddRange(new System.Windows.Forms.MenuItem[] {
																					  this.menuItemFile,
																					  this.menuItemEdit,
																					  this.Find,
																					  this.menuItemTagset,
																					  this.menuItemHelp});
			// 
			// menuItemFile
			// 
			this.menuItemFile.Index = 0;
			this.menuItemFile.MenuItems.AddRange(new System.Windows.Forms.MenuItem[] {
																						 this.menuItemOpen,
																						 this.menuItemSave,
																						 this.menuItemSaveAs,
																						 this.menuItem3,
																						 this.menuItemExit});
			this.menuItemFile.Text = "&File";
			this.menuItemFile.Click += new System.EventHandler(this.menuItemFile_Click);
			// 
			// menuItemOpen
			// 
			this.menuItemOpen.Index = 0;
			this.menuItemOpen.Shortcut = System.Windows.Forms.Shortcut.CtrlShiftO;
			this.menuItemOpen.Text = "&Open";
			this.menuItemOpen.Click += new System.EventHandler(this.menuItemOpen_Activate);
			// 
			// menuItemSave
			// 
			this.menuItemSave.Index = 1;
			this.menuItemSave.Shortcut = System.Windows.Forms.Shortcut.CtrlShiftS;
			this.menuItemSave.Text = "&Save";
			this.menuItemSave.Click += new System.EventHandler(this.menuItemSave_Activate);
			// 
			// menuItemSaveAs
			// 
			this.menuItemSaveAs.Index = 2;
			this.menuItemSaveAs.Shortcut = System.Windows.Forms.Shortcut.F12;
			this.menuItemSaveAs.Text = "Save &As";
			this.menuItemSaveAs.Click += new System.EventHandler(this.menuItemSaveAs_Activate);
			// 
			// menuItem3
			// 
			this.menuItem3.Index = 3;
			this.menuItem3.Text = "-";
			// 
			// menuItemExit
			// 
			this.menuItemExit.Index = 4;
			this.menuItemExit.Shortcut = System.Windows.Forms.Shortcut.AltF4;
			this.menuItemExit.Text = "E&xit";
			this.menuItemExit.Click += new System.EventHandler(this.menuItemExit_Activate);
			// 
			// menuItemEdit
			// 
			this.menuItemEdit.Index = 1;
			this.menuItemEdit.MenuItems.AddRange(new System.Windows.Forms.MenuItem[] {
																						 this.menuItemUndo,
																						 this.menuItemRedo,
																						 this.menuItem2,
																						 this.menuItemEncoding});
			this.menuItemEdit.Text = "&Edit";
			// 
			// menuItemUndo
			// 
			this.menuItemUndo.Index = 0;
			this.menuItemUndo.Shortcut = System.Windows.Forms.Shortcut.CtrlShiftU;
			this.menuItemUndo.Text = "&Undo";
			this.menuItemUndo.Click += new System.EventHandler(this.menuItemUndo_Activate);
			// 
			// menuItemRedo
			// 
			this.menuItemRedo.Index = 1;
			this.menuItemRedo.Shortcut = System.Windows.Forms.Shortcut.CtrlShiftR;
			this.menuItemRedo.Text = "&Redo";
			this.menuItemRedo.Click += new System.EventHandler(this.menuItemRedo_Activate);
			// 
			// menuItem2
			// 
			this.menuItem2.Index = 2;
			this.menuItem2.Text = "-";
			// 
			// menuItemEncoding
			// 
			this.menuItemEncoding.Index = 3;
			this.menuItemEncoding.MenuItems.AddRange(new System.Windows.Forms.MenuItem[] {
																							 this.menuItemASCII,
																							 this.menuItemUnicode,
																							 this.menuItemUTF8});
			this.menuItemEncoding.Text = "&Encoding";
			// 
			// menuItemASCII
			// 
			this.menuItemASCII.Index = 0;
			this.menuItemASCII.RadioCheck = true;
			this.menuItemASCII.Text = "ASCII";
			this.menuItemASCII.Click += new System.EventHandler(this.EncodingChanged);
			// 
			// menuItemUnicode
			// 
			this.menuItemUnicode.Index = 1;
			this.menuItemUnicode.RadioCheck = true;
			this.menuItemUnicode.Text = "Unicode";
			this.menuItemUnicode.Click += new System.EventHandler(this.EncodingChanged);
			// 
			// menuItemUTF8
			// 
			this.menuItemUTF8.Index = 2;
			this.menuItemUTF8.RadioCheck = true;
			this.menuItemUTF8.Text = "UTF-8";
			this.menuItemUTF8.Click += new System.EventHandler(this.EncodingChanged);
			// 
			// Find
			// 
			this.Find.Index = 2;
			this.Find.MenuItems.AddRange(new System.Windows.Forms.MenuItem[] {
																				 this.menuItemNextEntity,
																				 this.menuItemPrevEntity});
			this.Find.Text = "Fi&nd";
			// 
			// menuItemNextEntity
			// 
			this.menuItemNextEntity.Index = 0;
			this.menuItemNextEntity.Shortcut = System.Windows.Forms.Shortcut.F3;
			this.menuItemNextEntity.Text = "&Next Entity";
			this.menuItemNextEntity.Click += new System.EventHandler(this.menuItemNextEntity_Click);
			// 
			// menuItemPrevEntity
			// 
			this.menuItemPrevEntity.Index = 1;
			this.menuItemPrevEntity.Shortcut = System.Windows.Forms.Shortcut.ShiftF3;
			this.menuItemPrevEntity.Text = "&Prev Entity";
			this.menuItemPrevEntity.Click += new System.EventHandler(this.menuItemPrevEntity_Click);
			// 
			// menuItemTagset
			// 
			this.menuItemTagset.Index = 3;
			this.menuItemTagset.Text = "&Tag set";
			// 
			// menuItemHelp
			// 
			this.menuItemHelp.Index = 4;
			this.menuItemHelp.MenuItems.AddRange(new System.Windows.Forms.MenuItem[] {
																						 this.menuItemHelpTopic,
																						 this.menuItemAbout});
			this.menuItemHelp.Text = "&Help";
			// 
			// menuItemHelpTopic
			// 
			this.menuItemHelpTopic.Index = 0;
			this.menuItemHelpTopic.Text = "Help &Topics";
			this.menuItemHelpTopic.Click += new System.EventHandler(this.menuItemHelpTopic_Click);
			// 
			// menuItemAbout
			// 
			this.menuItemAbout.Index = 1;
			this.menuItemAbout.Text = "&About ";
			this.menuItemAbout.Click += new System.EventHandler(this.menuItemAbout_Click);
			// 
			// panelMain
			// 
			this.panelMain.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) 
				| System.Windows.Forms.AnchorStyles.Left) 
				| System.Windows.Forms.AnchorStyles.Right)));
			this.panelMain.Controls.Add(this.panelLeft);
			this.panelMain.Controls.Add(this.splitter1);
			this.panelMain.Controls.Add(this.panelRight);
			this.panelMain.Location = new System.Drawing.Point(8, 32);
			this.panelMain.Name = "panelMain";
			this.panelMain.Size = new System.Drawing.Size(1264, 696);
			this.panelMain.TabIndex = 3;
			// 
			// panelLeft
			// 
			this.panelLeft.BackColor = System.Drawing.SystemColors.Control;
			this.panelLeft.Controls.Add(this.groupBox2);
			this.panelLeft.Dock = System.Windows.Forms.DockStyle.Fill;
			this.panelLeft.Location = new System.Drawing.Point(0, 0);
			this.panelLeft.Name = "panelLeft";
			this.panelLeft.Size = new System.Drawing.Size(965, 696);
			this.panelLeft.TabIndex = 7;
			// 
			// groupBox2
			// 
			this.groupBox2.Controls.Add(this.rtbText);
			this.groupBox2.Dock = System.Windows.Forms.DockStyle.Fill;
			this.groupBox2.Location = new System.Drawing.Point(0, 0);
			this.groupBox2.Name = "groupBox2";
			this.groupBox2.Size = new System.Drawing.Size(965, 696);
			this.groupBox2.TabIndex = 1;
			this.groupBox2.TabStop = false;
			// 
			// rtbText
			// 
			this.rtbText.AccessibleRole = System.Windows.Forms.AccessibleRole.None;
			this.rtbText.Dock = System.Windows.Forms.DockStyle.Fill;
			this.rtbText.Location = new System.Drawing.Point(3, 20);
			this.rtbText.Name = "rtbText";
			this.rtbText.ReadOnly = true;
			this.rtbText.Size = new System.Drawing.Size(959, 673);
			this.rtbText.TabIndex = 0;
			this.rtbText.Text = "";
			this.rtbText.KeyDown += new System.Windows.Forms.KeyEventHandler(this.RichTextBox_KeyDown);
			this.rtbText.SelectionChanged += new System.EventHandler(this.rtbText_SelectionChanged);
			// 
			// splitter1
			// 
			this.splitter1.Dock = System.Windows.Forms.DockStyle.Right;
			this.splitter1.Location = new System.Drawing.Point(965, 0);
			this.splitter1.Name = "splitter1";
			this.splitter1.Size = new System.Drawing.Size(3, 696);
			this.splitter1.TabIndex = 6;
			this.splitter1.TabStop = false;
			// 
			// panelRight
			// 
			this.panelRight.Controls.Add(this.groupBox1);
			this.panelRight.Controls.Add(this.tabControl1);
			this.panelRight.Dock = System.Windows.Forms.DockStyle.Right;
			this.panelRight.Location = new System.Drawing.Point(968, 0);
			this.panelRight.Name = "panelRight";
			this.panelRight.Size = new System.Drawing.Size(296, 696);
			this.panelRight.TabIndex = 5;
			// 
			// groupBox1
			// 
			this.groupBox1.Dock = System.Windows.Forms.DockStyle.Bottom;
			this.groupBox1.Location = new System.Drawing.Point(0, 472);
			this.groupBox1.Name = "groupBox1";
			this.groupBox1.Size = new System.Drawing.Size(296, 224);
			this.groupBox1.TabIndex = 1;
			this.groupBox1.TabStop = false;
			this.groupBox1.Text = "Attributes";
			this.groupBox1.Leave += new System.EventHandler(this.groupBox1_Leave);
			// 
			// tabControl1
			// 
			this.tabControl1.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) 
				| System.Windows.Forms.AnchorStyles.Left) 
				| System.Windows.Forms.AnchorStyles.Right)));
			this.tabControl1.Controls.Add(this.tabPageAttributes);
			this.tabControl1.Controls.Add(this.tabPageProperties);
			this.tabControl1.Location = new System.Drawing.Point(0, 0);
			this.tabControl1.Name = "tabControl1";
			this.tabControl1.SelectedIndex = 0;
			this.tabControl1.Size = new System.Drawing.Size(297, 456);
			this.tabControl1.TabIndex = 0;
			this.tabControl1.TabStop = false;
			// 
			// tabPageAttributes
			// 
			this.tabPageAttributes.Controls.Add(this.lbxTerms);
			this.tabPageAttributes.Location = new System.Drawing.Point(4, 25);
			this.tabPageAttributes.Name = "tabPageAttributes";
			this.tabPageAttributes.Size = new System.Drawing.Size(289, 427);
			this.tabPageAttributes.TabIndex = 2;
			this.tabPageAttributes.Text = "Classes";
			// 
			// lbxTerms
			// 
			this.lbxTerms.Dock = System.Windows.Forms.DockStyle.Fill;
			this.lbxTerms.HorizontalScrollbar = true;
			this.lbxTerms.ItemHeight = 16;
			this.lbxTerms.Location = new System.Drawing.Point(0, 0);
			this.lbxTerms.Name = "lbxTerms";
			this.lbxTerms.Size = new System.Drawing.Size(289, 420);
			this.lbxTerms.TabIndex = 3;
			this.lbxTerms.DoubleClick += new System.EventHandler(this.lbxTerms_DoubleClick);
			// 
			// tabPageProperties
			// 
			this.tabPageProperties.Controls.Add(this.propertyGrid1);
			this.tabPageProperties.Location = new System.Drawing.Point(4, 22);
			this.tabPageProperties.Name = "tabPageProperties";
			this.tabPageProperties.Size = new System.Drawing.Size(289, 430);
			this.tabPageProperties.TabIndex = 1;
			this.tabPageProperties.Text = "Properties";
			// 
			// propertyGrid1
			// 
			this.propertyGrid1.CommandsVisibleIfAvailable = true;
			this.propertyGrid1.Dock = System.Windows.Forms.DockStyle.Fill;
			this.propertyGrid1.HelpVisible = false;
			this.propertyGrid1.LargeButtons = false;
			this.propertyGrid1.LineColor = System.Drawing.SystemColors.ScrollBar;
			this.propertyGrid1.Location = new System.Drawing.Point(0, 0);
			this.propertyGrid1.Name = "propertyGrid1";
			this.propertyGrid1.Size = new System.Drawing.Size(289, 430);
			this.propertyGrid1.TabIndex = 0;
			this.propertyGrid1.Text = "propertyGrid1";
			this.propertyGrid1.ToolbarVisible = false;
			this.propertyGrid1.ViewBackColor = System.Drawing.SystemColors.Window;
			this.propertyGrid1.ViewForeColor = System.Drawing.SystemColors.WindowText;
			this.propertyGrid1.PropertyValueChanged += new System.Windows.Forms.PropertyValueChangedEventHandler(this.propertyGrid1_PropertyValueChanged);
			// 
			// toolBar1
			// 
			this.toolBar1.Appearance = System.Windows.Forms.ToolBarAppearance.Flat;
			this.toolBar1.Buttons.AddRange(new System.Windows.Forms.ToolBarButton[] {
																						this.toolBarButtonOpen,
																						this.toolBarButtonSave,
																						this.toolBarButtonSep1,
																						this.toolBarButtonUndo,
																						this.toolBarButtonRedo});
			this.toolBar1.Dock = System.Windows.Forms.DockStyle.None;
			this.toolBar1.DropDownArrows = true;
			this.toolBar1.ImageList = this.imageList1;
			this.toolBar1.Location = new System.Drawing.Point(0, 0);
			this.toolBar1.Name = "toolBar1";
			this.toolBar1.ShowToolTips = true;
			this.toolBar1.Size = new System.Drawing.Size(1176, 28);
			this.toolBar1.TabIndex = 4;
			this.toolBar1.ButtonClick += new System.Windows.Forms.ToolBarButtonClickEventHandler(this.toolBar1_ButtonClick);
			// 
			// toolBarButtonOpen
			// 
			this.toolBarButtonOpen.ImageIndex = 0;
			this.toolBarButtonOpen.ToolTipText = "Open a file";
			// 
			// toolBarButtonSave
			// 
			this.toolBarButtonSave.ImageIndex = 1;
			this.toolBarButtonSave.ToolTipText = "Save your changes";
			// 
			// toolBarButtonSep1
			// 
			this.toolBarButtonSep1.Style = System.Windows.Forms.ToolBarButtonStyle.Separator;
			// 
			// toolBarButtonUndo
			// 
			this.toolBarButtonUndo.Enabled = false;
			this.toolBarButtonUndo.ImageIndex = 2;
			this.toolBarButtonUndo.ToolTipText = "Press to undo your changes";
			// 
			// toolBarButtonRedo
			// 
			this.toolBarButtonRedo.Enabled = false;
			this.toolBarButtonRedo.ImageIndex = 3;
			this.toolBarButtonRedo.ToolTipText = "Press to redo";
			// 
			// FormMain
			// 
			this.AllowDrop = true;
			this.AutoScaleBaseSize = new System.Drawing.Size(7, 17);
			this.ClientSize = new System.Drawing.Size(1272, 753);
			this.Controls.Add(this.toolBar1);
			this.Controls.Add(this.panelMain);
			this.Controls.Add(this.statusBar1);
			this.Font = new System.Drawing.Font("Tahoma", 10F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((System.Byte)(0)));
			this.helpProvider1.SetHelpString(this, "Named Entity Annotation");
			this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon")));
			this.Menu = this.mainMenu1;
			this.Name = "FormMain";
			this.helpProvider1.SetShowHelp(this, true);
			this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
			this.Text = "Named Entity Annotation";
			this.WindowState = System.Windows.Forms.FormWindowState.Maximized;
			this.KeyDown += new System.Windows.Forms.KeyEventHandler(this.FormMain_KeyDown);
			this.Closing += new System.ComponentModel.CancelEventHandler(this.FormMain_Closing);
			this.SizeChanged += new System.EventHandler(this.FormMain_SizeChanged);
			this.Load += new System.EventHandler(this.FormMain_Load);
			this.DragDrop += new System.Windows.Forms.DragEventHandler(this.FormMain_DragDrop);
			this.DragEnter += new System.Windows.Forms.DragEventHandler(this.FormMain_DragEnter);
			((System.ComponentModel.ISupportInitialize)(this.statusBarPanel1)).EndInit();
			((System.ComponentModel.ISupportInitialize)(this.statusBarPanel2)).EndInit();
			this.panelMain.ResumeLayout(false);
			this.panelLeft.ResumeLayout(false);
			this.groupBox2.ResumeLayout(false);
			this.panelRight.ResumeLayout(false);
			this.tabControl1.ResumeLayout(false);
			this.tabPageAttributes.ResumeLayout(false);
			this.tabPageProperties.ResumeLayout(false);
			this.ResumeLayout(false);

		}
		#endregion
		#region /* Init Properties */
		private void InitProperties()
		{
			bag1 = new PropertyBag();
			bag1.GetValue += new PropertySpecEventHandler(this.bag1_GetValue);
			bag1.SetValue += new PropertySpecEventHandler(this.bag1_SetValue);
			//Font 
			bag1.Properties.Add(new PropertySpec("Textbox", typeof(Font), "Font", "Select font for textbox"));
						
			// Color
			foreach(string stKey in htbColors.Keys)
			{
				string stToolTip = "Color of " + stKey + " class";
				bag1.Properties.Add(new PropertySpec(stKey, typeof(Color), "Color",
					stToolTip));
			}
			
			propertyGrid1.SelectedObject = bag1;
			
			// TODO: Add any initialization after the InitializeComponent call

		}
		private void bag1_GetValue(object sender, PropertySpecEventArgs e)
		{
			switch(e.Property.Category)
			{
				case "Font":
				switch (e.Property.Name)
				{	
					case "Textbox":
						e.Value = rtbText.Font;
						break;
					
				}
					break;
				case "Color":
					e.Value = Color.FromName(htbColors[e.Property.Name].ToString());
					break;
												
			}
		}
		private void bag1_SetValue(object sender, PropertySpecEventArgs e)
		{
			switch(e.Property.Category)
			{
				case "Font":
				switch (e.Property.Name)
				{	
					case "Textbox":
						rtbText.Font = (Font)e.Value;
						break;
					
				}
					break;
				case "Color":
					htbColors[e.Property.Name] = ((Color)e.Value).Name;
					break;
			
			}
		}
		
	
		#endregion
		/// <summary>
		/// The main entry point for the application.
		/// </summary>
		[STAThread]
		static void Main() 
		{
			Application.Run(new FormMain());
		}


		#region /* Init parameters */
		private bool InitParas()
		{
			try
			{
				htbClasses.Clear();
				htbColors.Clear();
				XmlDocument doc = new XmlDocument();
				doc.Load(stFileTag);
				XmlElement root = doc.DocumentElement;
				foreach(XmlNode node in  root.ChildNodes)
				{
					string stDisplay = node.Attributes[1].Value;
					htbClasses.Add(node.Name, new Hashtable());
					htbColors.Add(node.Name, node.Attributes[0].Value);
				
				}
				
				
			}
			catch(Exception e)
			{
				DialogResult DlgRes = MessageBox.Show(e.Message, "Named Entity Annotation - Init failed", MessageBoxButtons.AbortRetryIgnore, MessageBoxIcon.Error);
				if(DlgRes == DialogResult.Ignore)
					return false;
				if(DlgRes == DialogResult.Retry)
				{
					InitParas();
					return true;
				}
				if(DlgRes == DialogResult.Abort)
					Application.Exit();
				
			}

			return true;			
		}
		#endregion

		#region /* Load/Save settings in INI files. */
		public bool LoadSettings(string config_file)
		{
			try
			{
				if(!File.Exists(stFileConfig))
					return false;
				Ini iniConfig = new Ini(config_file);
				stEncoding = (string)iniConfig.GetValue(@"Settings", @"Encoding",@"");
				foreach(MenuItem item in menuItemEncoding.MenuItems)
					if(stEncoding == item.Text.Replace("&", ""))			
					{
						item.Checked = true;
						break;
					}
				string stName = (string)iniConfig.GetValue(@"Textbox", @"FontName",@"");
				string stSize = (string)iniConfig.GetValue(@"Textbox", @"FontSize",@"");
				if(stSize.Length > 0)
					rtbText.Font = new Font(stName, (float)Convert.ToDouble(stSize));
				

			}
			catch(Exception ex)
			{
				DialogResult DlgRes = MessageBox.Show("Cannot load parameters. Press OK to continue, Cancel to quit the application.\nError details:\n\t" + ex.Message, "Named Entity Annotation - Init failed", MessageBoxButtons.OKCancel, MessageBoxIcon.Error);
				if(DlgRes == DialogResult.OK)
					return false;
				else if(DlgRes == DialogResult.Cancel)
					Application.Exit();
				
			}
			return true;
			
		}

		public bool SaveSettings(string config_file)
		{
			try
			{
				Ini iniConfig = new Ini(config_file);
				iniConfig.SetValue(@"Settings", @"Encoding", stEncoding);
				iniConfig.SetValue(@"Textbox", @"FontName",  rtbText.Font.Name);
				iniConfig.SetValue(@"Textbox", @"FontSize",  rtbText.Font.Size.ToString());
				
			
			}
			catch(Exception ex)
			{
				DialogResult DlgRes = MessageBox.Show("Cannot save settings. Press OK to continue, Cancel to quit the application.\nError details:\n\t" + ex.Message, "Named Entity Annotation - save settings failed", MessageBoxButtons.OKCancel, MessageBoxIcon.Error);
				if(DlgRes == DialogResult.OK)
					return false;
				else if(DlgRes == DialogResult.Cancel)
					Application.Exit();
				
			}
			return true;
		}
		#endregion	

		#region /*  Private functions */
		
		private bool ConfirmSave()
		{
			if(hasChange)
			{
				DialogResult DlgRes = MessageBox.Show("Your file has been changed. Do you want to save your change", "Save file?", MessageBoxButtons.YesNoCancel, MessageBoxIcon.Question);
				if(DlgRes == DialogResult.Yes)
					return SaveFile(stFileName);
				if(DlgRes == DialogResult.No)
					return true;
				return false;
			}
			return true;
		}
		
		private bool SaveFile(string stFile)
		{
			try
			{
				string stContent = rtbText.Text;
				for (int i = arrEntities.Count - 1; i >= 0; i--)
				{
					Entity curEntity = (Entity)arrEntities[i];
					string stTag = "<NAME cl=\"" + curEntity.stClass + "\"";
					if(curEntity.stTag != "")
						stTag += " " + curEntity.stTag.Replace("_", " ");
					stTag += ">";
					int nStart = curEntity.nStart;
					stContent = stContent.Insert(nStart + curEntity.nLength , "</NAME>");
					stContent = stContent.Insert(nStart, stTag);
				}
				stContent = stContent.Replace("( <NAME", "(<NAME");
				stContent = stContent.Replace("</NAME> .", "</NAME>.");
				stContent = stContent.Replace("</NAME> ,", "</NAME>,");
				stContent = stContent.Replace("</NAME> )", "</NAME>)");
				StreamWriter sw = new StreamWriter(stFile, false, System.Text.Encoding.GetEncoding(stEncoding));
				sw.Write(stContent);
				sw.Close();

				hasChange = false;
			}
			catch(Exception e)
			{
				DialogResult DlgRes = MessageBox.Show(e.Message, "Named Entity Annotation - Save File Error", MessageBoxButtons.AbortRetryIgnore, MessageBoxIcon.Error);
				if(DlgRes == DialogResult.Ignore)
					return false;
				if(DlgRes == DialogResult.Retry)
				{
					SaveFile(stFile);
					return true;
				}
				if(DlgRes == DialogResult.Abort)
					Application.Exit();
				
			}
			return true;
		}
		
		private bool LoadFile(string stFile)
		{
			try
			{
				int nEnd = 0, nPos = 0, nLen = 0;
				isUpdating = true;
				
				
				StreamReader sr = new StreamReader(stFile, System.Text.Encoding.GetEncoding(stEncoding));
				curEncoding = sr.CurrentEncoding;
				string stContent = sr.ReadToEnd();
				sr.Close();
				arrEntities.Clear();
				stContent = stContent.Replace("</NAME>", "</NAME> ");
				stContent = stContent.Replace("<NAME", " <NAME");
				stContent = stContent.Replace("\r\n", "\n");
				stContent = stContent.Replace("  ", " ");
				stContent = stContent.Replace("  ", " ");
			
				Regex r = new Regex(@"\<NAME(.)+?\>",RegexOptions.Compiled);
				string stTemp = stContent;
				if(r.IsMatch(stTemp))
				{
					for (Match m = r.Match(stTemp); m.Success; m = m.NextMatch()) 
					{
						string sLWord = m.Value;
						string stWord = sLWord.Replace(" ", "_");
						stContent = stContent.Replace(sLWord, stWord);
												
					}
				}
				stTemp = stContent;
				
				//replace
				stTemp = Regex.Replace(stTemp, @"\<NAME(.)+?\>", string.Empty, RegexOptions.Compiled);
				stTemp = stTemp.Replace("</NAME>", string.Empty);
				rtbText.Text = stTemp;
				rtbText.Select(0, stTemp.Length);
				rtbText.SelectionColor = Color.Black;
				rtbText.Select(0,0);
				string[] stWords = stContent.Split(new char[2] {' ', '\n'});
				string stClass = "", stID = "", stTag = "", stWrd = "";
				string stCurID = "";
				int nStart = 0;
				Entity curEntity = new Entity("", "", 0);
				foreach(string stWord in stWords)
				{
					stClass = stCurClass;
					stWrd = stWord;
					stID = stCurID;
					stTag = "";
					if(stWord.StartsWith("<NAME"))
					{
						
						nPos = stWord.IndexOf("\""); //<NAME_cl="
						nEnd = stWord.IndexOf("\"", nPos + 1); //<NAME_cl="
						if(nEnd < 0)
							return false;
						stClass = stWord.Substring(nPos + 1, nEnd - nPos - 1);
						nPos = stWord.IndexOf(">", nEnd + 1);
						if(nPos < 0 )
							return false;
						if(nPos - nEnd < 2)
							stTag = "";
						else
							stTag = stWord.Substring(nEnd + 1, nPos - nEnd - 1);
						stWrd = stWrd.Substring(nPos + 1);
						stCurClass = stClass;
						nLen = 0;
						curEntity = new Entity(stClass, stTag, nStart);
						
					}
					if(stWrd.EndsWith("</NAME>"))
					{
						stWrd = stWrd.Substring(0, stWrd.Length - 7);
						stCurClass = "";
						stCurID = "";
						//stTag = "</NAME>";
						curEntity.nLength = nLen + stWrd.Length;
						arrEntities.Add(curEntity);
					}
					nLen += stWrd.Length + 1;
					nStart += stWrd.Length + 1;
					isUpdating = false;
					
				}
			}
			catch(Exception e)
			{
				DialogResult DlgRes = MessageBox.Show(e.Message, "Named Entity Annotation - Load Data Error", MessageBoxButtons.AbortRetryIgnore, MessageBoxIcon.Error);
				if(DlgRes == DialogResult.Ignore)
					return false;
				if(DlgRes == DialogResult.Retry)
				{
					LoadFile(stFile);
					return true;
				}
				if(DlgRes == DialogResult.Abort)
					Application.Exit();
				
			}
			return true;
		}
		private bool UpdateColor()
		{
			try
			{
				isUpdating = true;
				for (int i = 0; i < arrEntities.Count ; i++)
				{
					Entity curEntity = (Entity)arrEntities[i];
					if(htbColors.Contains(curEntity.stClass))
					{
						Color curColor = Color.FromName(htbColors[curEntity.stClass].ToString());
						rtbText.Select(curEntity.nStart, curEntity.nLength);
						rtbText.SelectionColor = curColor;
					}
					rtbText.Select(0,0);
				}
				isUpdating = false;

			}
			catch(Exception e)
			{
				DialogResult DlgRes = MessageBox.Show(e.Message, "Named Entity Annotation - Update color error", MessageBoxButtons.AbortRetryIgnore, MessageBoxIcon.Error);
				if(DlgRes == DialogResult.Ignore)
					return false;
				if(DlgRes == DialogResult.Retry)
				{
					UpdateColor();
					return true;
				}
				if(DlgRes == DialogResult.Abort)
					Application.Exit();
				
			}
			return true;

		}

		private int FindEntityIndex(int nStart, int nLength)
		{
			int low, high, mid;
			low = 0; high = arrEntities.Count - 1;
			while(low <= high) 
			{
				mid = (low+high)/2;
				Entity curEntity = (Entity)arrEntities[mid];
				if(nStart < curEntity.nStart)
					high = mid-1;
				else if(nStart + nLength > curEntity.nStart + curEntity.nLength) low = mid+1;
				else return mid; /* found */
			}
			return -1;

		}
		private void UpdateColor(int nPos)
		{
			if(nPos < 0 || nPos >= arrEntities.Count)
				return;
			Entity curEntity = (Entity)arrEntities[nPos];
			rtbText.Select(curEntity.nStart, curEntity.nLength);
			rtbText.SelectionColor = Color.FromName(htbColors[curEntity.stClass].ToString());
		}
		private void SetEntityID()
		{
			if(isUpdating || lbxTerms.SelectedIndex < 0 || rtbText.Text.Length < 1)
				return;
			try
			{
				if(nCurPos < 0 && lbxTerms.SelectedItem.ToString() != "NONE")
				{
					int nStart = rtbText.SelectionStart;
					int nEnd = rtbText.SelectionStart + rtbText.SelectionLength;
					string stContent = rtbText.Text;
					while(nStart < stContent.Length && stContent[nStart] == ' ')
						nStart++;
					while(nStart > 0 && stContent[nStart - 1] != ' ')
						nStart--;

					while(nEnd > 0 && stContent[nEnd] == ' ')
						nEnd--;
					while(nEnd < stContent.Length - 1 && stContent[nEnd + 1] != ' ')
						nEnd++;
					Entity curEntity = new Entity(lbxTerms.SelectedItem.ToString(), "", nStart, nEnd - nStart + 1);
					int i = 0;
					for(i = 0; i < arrEntities.Count; i++)
					{
						Entity TmpEntity = (Entity)arrEntities[i];
						if(curEntity.nStart < TmpEntity.nStart)
							break;
					}
					arrUndo.Add(curEntity);
					menuItemUndo.Enabled = true;
					toolBarButtonUndo.Enabled = true;
					arrEntities.Insert(i, curEntity);
					UpdateColor(i);
					hasChange = true;
				}
				else
				{
					Entity curEntity = (Entity)arrEntities[nCurPos];
					if(lbxTerms.SelectedItem.ToString() != curEntity.stClass)
					{
						arrUndo.Add(curEntity);
						menuItemUndo.Enabled = true;
						toolBarButtonUndo.Enabled = true;
						if(lbxTerms.SelectedItem.ToString() == "NONE")
						{
							arrEntities.RemoveAt(nCurPos);
						}else
						{
							curEntity.stClass = lbxTerms.SelectedItem.ToString();
							arrEntities[nCurPos] = curEntity;
						}
						
						UpdateColor(nCurPos);
						hasChange = true;
					}
				}
				TagLabel tlb = (TagLabel)arrActiveTags[lbxTerms.SelectedIndex];
				GenerateUCAttr(tlb);


			}
			catch(Exception ex)
			{
				DialogResult DlgRes = MessageBox.Show("An error accured. Press OK to continue, Cancel to quit the application.\nError details:\n\t" + ex.Message, "Named Entity Annotation", MessageBoxButtons.OKCancel, MessageBoxIcon.Error);
				if(DlgRes == DialogResult.OK)
					return ;
				else if(DlgRes == DialogResult.Cancel)
					Application.Exit();
				
			}
			rtbText.Focus();
			return;
		
		}
		
		private void FindFirstEntity(int nStart, bool isForward)
		{
			if(isForward)
				nStart++;
			else
				nStart--;
			if(nStart < 0 || nStart >= rtbText.Text.Length)
				nStart = 0;
			if(arrEntities.Count == 0)
				return;
			try
			{
				int i = 0;
				if(isForward)
				{
					for(i = 0; i < arrEntities.Count; i++)
					{
						Entity nEntity = (Entity)arrEntities[i];
						if(nEntity.nStart >= nStart)
							break;
					}
				}else
				{
					for(i = arrEntities.Count - 1; i >= 0;  i--)
					{
						Entity nEntity = (Entity)arrEntities[i];
						if(nEntity.nStart < nStart)
							break;
					}

				}
				
				if(i >= arrEntities.Count || i < 0)
				{
					MessageBox.Show("No more entities found from this starting position.", "Find entities");
					return;
				}
				Entity eEntity = (Entity)arrEntities[i];
				rtbText.Select(eEntity.nStart, eEntity.nLength);
				rtbText.Focus();

			
			}
			catch(Exception ex)
			{
				DialogResult DlgRes = MessageBox.Show("An error accrued. Press OK to continue, Cancel to quit the application.\nError details:\n\t" + ex.Message, "Named Entity Annotation", MessageBoxButtons.OKCancel, MessageBoxIcon.Error);
				if(DlgRes == DialogResult.OK)
					return ;
				else if(DlgRes == DialogResult.Cancel)
					Application.Exit();
				
			}
			return;
		}
	
		private void OpenFile()
		{
			try
			{
				openFileDialog1.Multiselect = false;
				openFileDialog1.Filter = "Text files (*.txt)|*.txt|All files (*.*)|*.*";
				if(openFileDialog1.ShowDialog() == DialogResult.OK)
				{
					stFileName = openFileDialog1.FileName;
					LoadFile(stFileName);
					this.Text = "Named Entity Annotation - " + stFileName.Substring(stFileName.LastIndexOf("\\") + 1);
					statusBar1.Panels[0].Text = stFileName;
					UpdateColor();
				}
			}
			catch(Exception ex)
			{
				DialogResult DlgRes = MessageBox.Show("An error accured. Press OK to continue, Cancel to quit the application.\nError details:\n\t" + ex.Message, "Named Entity Annotation", MessageBoxButtons.OKCancel, MessageBoxIcon.Error);
				if(DlgRes == DialogResult.OK)
					return ;
				else if(DlgRes == DialogResult.Cancel)
					Application.Exit();
				
			}
			return;
		}
		private void DoUndo()
		{	
			try
			{
				if(arrUndo.Count > 0)
				{
					Entity bEntity;
					bEntity = (Entity)arrUndo[arrUndo.Count - 1];
					int i;
					for(i = 0; i < arrEntities.Count; i++)
					{
						Entity eEntity = (Entity)arrEntities[i];
						if(eEntity.nStart >= bEntity.nStart)
							break;
					}
					if(i < arrEntities.Count)
					{
						Entity eEntity = (Entity)arrEntities[i];
						if(eEntity.nStart == bEntity.nStart && eEntity.nLength == bEntity.nLength)
						{
							if(eEntity.stClass == bEntity.stClass && eEntity.stTag == bEntity.stTag)//inserted
								arrEntities.RemoveAt(i);
							else
							{
								arrEntities[i] = bEntity;
								bEntity = eEntity;
							}
						}else
							arrEntities.Insert(i, bEntity);
					}else
						arrEntities.Add(bEntity);
					UpdateColor(i);
				
					arrRedo.Add(bEntity);
					arrUndo.RemoveAt(arrUndo.Count - 1);
					
					menuItemRedo.Enabled = true;
					toolBarButtonRedo.Enabled = true;
					rtbText.Focus();
					rtbText.Select(bEntity.nStart, bEntity.nLength);
					if(arrUndo.Count < 1)
					{
						menuItemUndo.Enabled = false;
						
						toolBarButtonUndo.Enabled = false;
					}
					
				}
			}
			catch(Exception ex)
			{
				DialogResult DlgRes = MessageBox.Show("An error accured. Press OK to continue, Cancel to quit the application.\nError details:\n\t" + ex.Message, "Named Entity Annotation", MessageBoxButtons.OKCancel, MessageBoxIcon.Error);
				if(DlgRes == DialogResult.OK)
					return ;
				else if(DlgRes == DialogResult.Cancel)
					Application.Exit();
				
			}
			return;
		}
		private void DoRedo()
		{
			try
			{
				if(arrRedo.Count > 0)
				{
					Entity bEntity;
					bEntity = (Entity)arrRedo[arrRedo.Count - 1];
					int i;
					for(i = 0; i < arrEntities.Count; i++)
					{
						Entity eEntity = (Entity)arrEntities[i];
						if(eEntity.nStart >= bEntity.nStart)
							break;
					}
					if(i < arrEntities.Count)
					{
						Entity eEntity = (Entity)arrEntities[i];
						if(eEntity.nStart == bEntity.nStart && eEntity.nLength == bEntity.nLength)
						{
							if(eEntity.stClass == bEntity.stClass && eEntity.stTag == bEntity.stTag)//inserted
								arrEntities.RemoveAt(i);
							else
							{
								arrEntities[i] = bEntity;
								bEntity = eEntity;
							}
						}
						else
							arrEntities.Insert(i, bEntity);
					}
					else
						arrEntities.Add(bEntity);
					
					UpdateColor(i);
					arrUndo.Add(bEntity);
					arrRedo.RemoveAt(arrRedo.Count - 1);
					
					menuItemUndo.Enabled = true;
					toolBarButtonUndo.Enabled = true;
					rtbText.Focus();
					rtbText.Select(bEntity.nStart, bEntity.nLength);
					if(arrRedo.Count < 1)
					{
						menuItemRedo.Enabled = false;
						toolBarButtonRedo.Enabled = false;
					}	
				}
			}
			catch(Exception ex)
			{
				DialogResult DlgRes = MessageBox.Show("An error accured. Press OK to continue, Cancel to quit the application.\nError details:\n\t" + ex.Message, "Named Entity Annotation", MessageBoxButtons.OKCancel, MessageBoxIcon.Error);
				if(DlgRes == DialogResult.OK)
					return ;
				else if(DlgRes == DialogResult.Cancel)
					Application.Exit();
				
			}
			return;
		}
		#endregion

		#region /* System Events */

		private void FormMain_Load(object sender, System.EventArgs e)
		{
			if(File.Exists(stFileHelp))
				helpProvider1.HelpNamespace = stFileHelp;
			
			menuItemUndo.Enabled = false;
			menuItemRedo.Enabled = false;
			LoadXMLTagset(stFileTag, ref arrActiveTags);
			LoadSettings(stFileConfig);
		
			InitProperties();
			
		}
		private void rtbText_SelectionChanged(object sender, System.EventArgs e)
		{
			if(isUpdating)
				return;
			if(rtbText.SelectionStart < 0 )
				return;
			try
			{
				nCurPos = FindEntityIndex(rtbText.SelectionStart, rtbText.SelectionLength);
				if(nCurPos >= 0)
				{
					Entity curEntity = (Entity)arrEntities[nCurPos];
					for(int i = 0; i < lbxTerms.Items.Count; i++)
					{
						if(lbxTerms.Items[i].ToString() == curEntity.stClass)
						{
							lbxTerms.SelectedIndex = i;
							TagLabel tlb = (TagLabel)arrActiveTags[i];
							GenerateUCAttr(tlb);
							return;
						}
					}
				}
				lbxTerms.SelectedIndex = 0;
				groupBox1.Controls.Clear();
	
			}
			catch(Exception ex)
			{
				DialogResult DlgRes = MessageBox.Show("An error accrued. Press OK to continue, Cancel to quit the application.\nError details:\n\t" + ex.Message, "Named Entity Annotation", MessageBoxButtons.OKCancel, MessageBoxIcon.Error);
				if(DlgRes == DialogResult.OK)
					return ;
				else if(DlgRes == DialogResult.Cancel)
					Application.Exit();
				
			}
			return;
	

		}
		
		private void menuItemOpen_Activate(object sender, System.EventArgs e)
		{
			OpenFile();
		}

		private void menuItemSave_Activate(object sender, System.EventArgs e)
		{
			SaveFile(stFileName);			
		}

		private void menuItemSaveAs_Activate(object sender, System.EventArgs e)
		{
			try
			{
				saveFileDialog1.Filter = "Text files (*.txt)|*.txt|All files (*.*)|*.*";
				if(saveFileDialog1.ShowDialog() == DialogResult.OK)
				{
					if(saveFileDialog1.FileName.Length > 0)
					{
						stFileName = saveFileDialog1.FileName;
						SaveFile(stFileName);
						this.Text = "Named Entity Annotation - " + stFileName.Substring(stFileName.LastIndexOf("\\") + 1);
						statusBar1.Panels[0].Text = stFileName;
					}
				}
			}
			catch(Exception ex)
			{
				DialogResult DlgRes = MessageBox.Show("An error accured. Press OK to continue, Cancel to quit the application.\nError details:\n\t" + ex.Message, "Named Entity Annotation", MessageBoxButtons.OKCancel, MessageBoxIcon.Error);
				if(DlgRes == DialogResult.OK)
					return ;
				else if(DlgRes == DialogResult.Cancel)
					Application.Exit();
				
			}
			return;
			
		}

		private void menuItemExit_Activate(object sender, System.EventArgs e)
		{
			if(ConfirmSave())
			{
				SaveXMLTagset(stFileTag);
				SaveSettings(stFileConfig);
				Application.Exit();
			}
		}

		private void menuItemUndo_Activate(object sender, System.EventArgs e)
		{
			DoUndo();
		}

		private void menuItemRedo_Activate(object sender, System.EventArgs e)
		{
			DoRedo();		
		}
	
		private void FormMain_Closing(object sender, System.ComponentModel.CancelEventArgs e)
		{
			if(ConfirmSave())
			{
				SaveXMLTagset(stFileTag);
				SaveSettings(stFileConfig);
				Application.Exit();
			}
			e.Cancel = true;
				
		}
	
		private void FormMain_DragDrop(object sender, System.Windows.Forms.DragEventArgs e)
		{
			if (e.Data.GetDataPresent(DataFormats.FileDrop))
			{
				String[] stFileNames = e.Data.GetData(DataFormats.FileDrop) as String[];
				if (stFileNames != null && stFileNames.Length > 0)
				{
					stFileName = stFileNames[0];
					LoadFile(stFileName);
					UpdateColor();
				}
			}

		}

		private void FormMain_DragEnter(object sender, System.Windows.Forms.DragEventArgs e)
		{
			if (e.Data.GetDataPresent(DataFormats.FileDrop))
			{
				string[] filenames = e.Data.GetData(DataFormats.FileDrop) as string[];
				if (filenames != null)
				{
					e.Effect = DragDropEffects.Copy;
				}
				else
				{
					e.Effect = DragDropEffects.None;
				}
			}
			else
			{
				e.Effect = DragDropEffects.None;
			}


		}

		private void FormMain_SizeChanged(object sender, System.EventArgs e)
		{
			int nLength  = statusBar1.Size.Width;
			if(nLength <= statusBar1.Panels[0].MinWidth || nLength <= statusBar1.Panels[1].MinWidth)
				return;
			statusBar1.Panels[0].Width= 4*nLength/5;
			statusBar1.Panels[1].Width = nLength/5;
			
			
			
		}

	
		private void FormMain_KeyDown(object sender, System.Windows.Forms.KeyEventArgs e)
		{
			switch (e.KeyData)
			{
				case Keys.Tab:
					if(rtbText.Focused)
						rtbText.Focus();
					break;
				case Keys.Control|Keys.Shift|Keys.E:
					ExportVoc();
					break;

				
			}
		
		

		
		}

		private void ExportVoc()
		{
			try{
				StreamWriter sw = new StreamWriter("Vocabulary.txt", false, System.Text.Encoding.Unicode);
				foreach(string stKey in htbClasses.Keys)
				{
					sw.WriteLine("#" + stKey);
					Hashtable htbIDs = (Hashtable)htbClasses[stKey];
					foreach(RootTerm rootTerm in htbIDs.Values)
					{
						string stText = rootTerm.stLabel + ": ";
						for (int i = 0; i < rootTerm.arrSynonymTerms.Count; i++)
						{
							Term nTerm = (Term)rootTerm.arrSynonymTerms[i];
							if(nTerm.stLanguage == stLanguage)
								stText += nTerm.stLabel + ", ";
						}
						stText = stText.TrimEnd(new char[3] {':', ',', ' '});
						sw.WriteLine(stText);
					
					
					}
				}
				sw.Close();
				
				MessageBox.Show("Export complete!!!");
			}catch(Exception e)
			{
				MessageBox.Show(e.Message);
			}
		}
		private void lbxTerms_DoubleClick(object sender, System.EventArgs e)
		{
			
			SetEntityID();
		}

		private void propertyGrid1_PropertyValueChanged(object s, System.Windows.Forms.PropertyValueChangedEventArgs e)
		{
			UpdateColor();
		}

		private void EncodingChanged(object sender, System.EventArgs e)
		{
			foreach(MenuItem item in menuItemEncoding.MenuItems)
				item.Checked = false;
			stEncoding = ((MenuItem)sender).Text.Replace("&", "");
			((MenuItem)sender).Checked= true;
		}

		private void lbxTerms_Leave(object sender, System.EventArgs e)
		{
			rtbText.Focus();
		}

		private void toolBar1_ButtonClick(object sender, System.Windows.Forms.ToolBarButtonClickEventArgs e)
		{
			switch(e.Button.ImageIndex) {
			case 0:
				OpenFile();
				break;
			case 1:
				SaveFile(stFileName);
				break;
			case 2:
				DoUndo();
				break;
		
			case 3:
				DoRedo();
				break;
		
				default:
					break;
			}

		}

		private void menuItemNextEntity_Click(object sender, System.EventArgs e)
		{
			FindFirstEntity(rtbText.SelectionStart,  true);
		}

		private void menuItemPrevEntity_Click(object sender, System.EventArgs e)
		{
			FindFirstEntity(rtbText.SelectionStart, false);
		}

		
		
#endregion	

		private void menuItemHelpTopic_Click(object sender, System.EventArgs e)
		{
			System.Diagnostics.Process.Start(stFileHelp);
		}

		private void menuItemAbout_Click(object sender, System.EventArgs e)
		{
			FormAbout frmAbout = new FormAbout();
			frmAbout.Show();
		}

		private void menuItemFile_Click(object sender, System.EventArgs e)
		{
		
		}
		
		private bool LoadXMLTagset(string fileName, ref ArrayList arrTags)
		{
			xDoc.Load(fileName);
			XmlElement root = xDoc.DocumentElement;
			XmlDocument doc = new XmlDocument();
			arrTags.Clear();
			htbColors.Clear();
			foreach(XmlElement xe in root.ChildNodes)
			{
				TagLabel tag = new TagLabel();
				tag.ClassName = xe.GetAttribute("Name");
				tag.Color = xe.GetAttribute("Color");
				htbColors.Add(tag.ClassName, tag.Color);
				tag.Atributes = new ArrayList();
				if(xe.GetAttribute("Shortcut").Length > 0)
					tag.Shortcut = xe.GetAttribute("Shortcut")[0];
				tag.Description = xe.GetAttribute("Description");
				
				foreach(XmlElement mxe in xe.ChildNodes)
				{
					TagAttribute atribute = new TagAttribute(mxe.GetAttribute("Name"));
					string stTemp = "";
					foreach(XmlElement mmxe in mxe.ChildNodes)
					{
						stTemp += mmxe.InnerText + "#";
					}
					atribute.Values = stTemp;
					tag.Atributes.Add(atribute);
				}
				lbxTerms.Items.Add(tag.ClassName);
				MenuItem item = new MenuItem();
				item.Text = tag.ClassName;
				item.Shortcut = GetShortCut("Ctrl" + tag.Shortcut);
				menuItemTagset.MenuItems.Add(item);
				item.Click += new System.EventHandler(this.menuItemAnnotate_Click);
				arrTags.Add(tag);
			}
			
			return true;
		}
		private bool SaveXMLTagset(string fileName)
		{
			XmlElement root = xDoc.DocumentElement;
			foreach(XmlElement node in root.ChildNodes)
			{
				string stClass = node.GetAttribute("Name");
				if(htbColors.Contains(stClass))
					node.SetAttribute("Color", htbColors[stClass].ToString());
				
			}
            xDoc.Save(fileName);			
			return true;
		}		
		private void GenerateUCAttr(TagLabel tag)
		{
			int i = 0;
			this.groupBox1.Controls.Clear();
			UCAttribute ucAttr;
			foreach(TagAttribute attribute in tag.Atributes)
			{
				ucAttr = new UCAttribute();
				ucAttr.AttributeName = attribute.Name;
				ucAttr.AttributeValues = attribute.Values;
				ucAttr.Location = new System.Drawing.Point(8, 15 + i*50);
				ucAttr.Name = "ucAttr";
				ucAttr.Size = new System.Drawing.Size(groupBox1.Size.Width - 10, 40);
				ucAttr.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) 
					| System.Windows.Forms.AnchorStyles.Right)));
				this.groupBox1.Controls.Add(ucAttr);
				i++;
			
			}
			if(nCurPos < 0 || nCurPos >= arrEntities.Count)
				return;
			Entity curEntity = (Entity)arrEntities[nCurPos];
			string stTag = curEntity.stTag;
			if(stTag == "")
				return;
			foreach(UCAttribute ucAtt in groupBox1.Controls)
			{
				int nIndex = stTag.IndexOf(ucAtt.AttributeName + "=");
				if(nIndex != -1)
				{
					nIndex += ucAtt.AttributeName.Length + 1;
					int nLast = stTag.IndexOf("_", nIndex) > -1 ? stTag.IndexOf("_", nIndex) : stTag.Length;
					string stValue = stTag.Substring(nIndex, nLast - nIndex );
					ucAtt.AttributeValue = stValue.Trim('"');
				}
			}

		}
		private void menuItemAnnotate_Click(object sender, System.EventArgs e)
		{
			MenuItem item = (MenuItem)sender;
			for(int i = 0; i < lbxTerms.Items.Count; i++)
			{
				if (lbxTerms.Items[i].ToString() == item.Text)
				{
					lbxTerms.SelectedIndex = i;
					SetEntityID();
					break;
				}
			}
		}

		private void groupBox1_Leave(object sender, System.EventArgs e)
		{
			if (nCurPos < 0 || nCurPos >= arrEntities.Count)
				return;
			string stTag = "";
			foreach(UCAttribute ucAtt in groupBox1.Controls)
			{
				if(ucAtt.AttributeValue != "null")
					stTag += ucAtt.AttributeName + "=\"" + ucAtt.AttributeValue + "\"_";
			}
			Entity curEntity = (Entity)arrEntities[nCurPos];
			curEntity.stTag = stTag.Trim('_');
			arrEntities[nCurPos] = curEntity;
		}

		private void RichTextBox_KeyDown(object sender, System.Windows.Forms.KeyEventArgs e)
		{
			if ( e.Modifiers == Keys.Control )
			{
				switch(e.KeyCode)
				{
					// you can add what ever keys you want to handle here
					case Keys.C:
					case Keys.X:
					case Keys.V:
					case Keys.Z:
					case Keys.D:
					case Keys.B:
					case Keys.I:
					case Keys.U:
					case Keys.E:
					case Keys.J:
					case Keys.L:
					case Keys.R:
						e.Handled = true;
						break;
					default:
						break;
				}
			}
		
		}
		


	}
}


